/**
 * AudioPlayer V1.0.0
 * Author：linxl
 */
import $ from 'jquery';
import Util from './utils/util';
import './styles/simple-voice.scss';

const client = Util.client();
//初始化--私有方法
const init = Symbol('init');
//简版语音--私有方法 and 私有属性
const initSimpleVoice = Symbol('initSimpleVoice');
const eventsVocie = Symbol('eventsVocie');
const updateTotoleTimeVocie = Symbol('updateTotoleTimeVocie');
const changeStatusVocie = Symbol('changeStatusVocie');

const currentStatusVocie = Symbol('currentStatusVocie');

//通用--私有方法
const autoplay = Symbol('autoplay');
const playButton = Symbol('playButton');
const events = Symbol('events');

//私有属性
const options = Symbol('options');
const eventArr = Symbol('eventArr');


class AudioPlayer{

    constructor($ele, params){
        let defaultOptions = {
            type: 'music', //播放器类型：简版语音-vocie、转盘音乐播放器-music
            url: '',
            autoplay: false,
            startTime: 0,//开始播放时间
        };

        this[options] = $.extend(defaultOptions, params || {});
        //移动端将自动播放设置为false
        this[options].autoplay = client.ISMOBILE ? false : this[options].autoplay;
        this[eventArr] = {};//播放器事件监听堆栈
        this.audioUUID = new Date().getTime() + '_' + Util.uuid();//生成的唯一性audio.id
        this.audio = null
        this.$audio = null;
        this.$parent = $ele;
        //初始化
        this[init]();
    }

    [init](){
        if(!this.$parent) return false;
        
        if(this[options].type == "music"){

        }else if(this[options].type == "vocie"){
            //渲染-语音精简样式
            this[initSimpleVoice]();
        }
    }

    //simple voice-语音精简样式
    [initSimpleVoice](){
        this.$containerWrap = null;
        this.$container = null;
        this.$statusBox = null;
        this.$timeBox = null;
        this.$progress = null;
        this[currentStatusVocie] = '';//当前播放状态: playing, pause, ended, error

        //classname列表
        this[options] = $.extend(this[options], {
            containerWrapClass: 'audio-container-wrap',
            containerClass: 'audio-container',
            statusContainerClass: 'audio-status',
            progressContainerWrapClass: 'progress-container-wrap',
            progressContainerClass: 'progress-container',
            containerBeforeprogressClass: 'progress',
            totalTimeContainerClass: 'audio-time',
            playingClass: 'playing',
            errorClass: 'error'
        });

        //生成DOM结构
        this.$parent.html('<div class="' + this[options].containerWrapClass + '">'
                            + '<div class="' + this[options].containerClass + '">'
                                + '<audio id="' + this.audioUUID + '" width="1" height="1" preload="metadata" src="' + this[options].url + '">您的浏览器不支持audio标签</audio>'
                                + '<span class="' + this[options].statusContainerClass + '"></span>'
                                + '<div class="' + this[options].progressContainerWrapClass + '"><div class="' + this[options].progressContainerClass + '"></div></div>'
                            + '</div>'
                            + '<span class="' + this[options].totalTimeContainerClass + '"></span>'
                        + '</div>');
        delete this.audioUUID;
        this.$audio = this.$parent.find('audio');
        this.audio = this.$audio[0];
        this.$containerWrap = this.$parent.find('.'+this[options].containerWrapClass);
        this.$container = this.$parent.find('.'+this[options].containerClass)
        this.$statusBox = this.$parent.find('.'+this[options].statusContainerClass);
        this.$timeBox = this.$parent.find('.'+this[options].totalTimeContainerClass);
        this.$progress = this.$parent.find('.'+this[options].progressContainerClass);

        this[eventsVocie]();
        this[autoplay]();
        this[playButton]();
        this[events]();
    }
    //语音-事件
    [eventsVocie](){
        // event handler
        var loadedmetadataHandler = function(event) {
            changeStatusHandler('');
           this[updateTotoleTimeVocie]();
        }.bind(this);
        var canplayHandler = function(event) {
            if(this[options].autoplay) this.$audio.trigger('playBtn.toggle', Object.assign({}, event, {"xtStateType": "play"}));
        }.bind(this);
        var changeStatusHandler = function(type){
            this[currentStatusVocie] = type;
            this[changeStatusVocie]();
        }.bind(this);
        var setCurrentZero = function(){
            this.audio.currentTime = 0;
            this.$container.removeClass(this[options].containerBeforeprogressClass);
            this.$progress.css({
                width: 0
            });
        }.bind(this);
        var errorHandler = function(event){
            changeStatusHandler('error');
            setCurrentZero();
            this.$audio.trigger('playBtn.toggle', Object.assign({}, event, {"xtStateType": "pause"}));
        }.bind(this);

        this.$container.on('click.vocie', function(event){
            event.stopPropagation();
            event.cancelBubble = true
            if(this[currentStatusVocie] == 'error'){
                return;
            }
            if(this[currentStatusVocie] == 'ended'){
                setCurrentZero();
            }
            this.audio.volume = 1.0;
            this.audio.playbackRate = 1.0;
            this.$audio.trigger('playBtn.toggle', Object.assign({}, event));
            return false;
        }.bind(this))
        
        this.$audio.on('loadedmetadata.vocie', loadedmetadataHandler);
        this.$audio.on('durationchange.vocie', loadedmetadataHandler);
        this.$audio.on('canplay.vocie', canplayHandler);
        this.$audio.on('playing.vocie', function(e){
            changeStatusHandler('playing');
        }.bind(this));
        this.$audio.on('pause.vocie', function(e){
            setCurrentZero();
            changeStatusHandler('pause');
        }.bind(this));
        this.$audio.on('ended.vocie', function(e){
            changeStatusHandler('ended');
        }.bind(this));

        //进度条
        // this.$audio.on('timeupdate.vocie', function(event) {
        //     var _currentTime = this.audio.currentTime;
        //     var _duration = this.audio.duration;
        //     if(_currentTime>0){
        //         this.$container.addClass(this[options].containerBeforeprogressClass);
        //         var processNum = _currentTime / _duration * 100;
        //         var process = processNum + '%';
        //         this.$progress.css({
        //             width: process
        //         });
        //     }else{
        //         this.$container.removeClass(this[options].containerBeforeprogressClass);
        //         this.$progress.css({
        //             width: 0
        //         });
        //     }
        // }.bind(this));
        this.$audio.on('error.vocie', errorHandler);
    }
    //语音-更新时间totaltime
    [updateTotoleTimeVocie](){
        var time = Math.round(this.audio.duration);
        var seconds = time % 60;
        var minutes = Math.floor(time / 60);
        this.$timeBox.html((minutes ? (Util.addZero(minutes) + "' ") : "") + Util.addZero(seconds) + '"');
    }
    //语音-改变状态class
    [changeStatusVocie](){
        if(this[currentStatusVocie] == 'playing'){
            this.$statusBox.removeClass(this[options].errorClass).addClass(this[options].playingClass);
        }else if(this[currentStatusVocie] == 'error'){
            this.$statusBox.removeClass(this[options].playingClass).addClass(this[options].errorClass);
        }else{
            this.$statusBox.removeClass(this[options].playingClass).removeClass(this[options].errorClass);
        }
    }
    //设置自动播放
    [autoplay]() {
        // 自动播放
        if (this.$audio.prop('autoplay') || this[options].autoplay) {
            this.$audio.attr('autoplay', true);
            this.$audio.prop('autoplay', true);
            this.audio.autoplay = true;
        }
    }
    //封装播放，暂停事件-防止报错
    [playButton](){
        this.$audio.on('playBtn.toggle', function(e, data) {
            var xtStateType = null;
            if(data && "xtStateType" in data && data.xtStateType) xtStateType = data.xtStateType;
            if (this.audio.paused) {
                if(xtStateType != "pause"){
                    var playPromise = this.audio.play();
                    var _this = this;
                    if(playPromise !== undefined){
                        playPromise.then(function(){
                            _this.audio.play();
                        }).catch(function(e){
                            
                        });
                    }
                }
            } else {
                if(xtStateType != "play"){
                    this.audio.pause();
                }
            }
        }.bind(this));
    }
    //公有方法
    play(){
        this.$audio.trigger('playBtn.toggle', {"xtStateType": "play"});
    }
    //公有方法
    pause(){
        this.$audio.trigger('playBtn.toggle', {"xtStateType": "pause"});
    }
    //给播放器实例绑定事件-公有方法
    on(type, callback){
        var $this = this;
        var isHas = false;
        for(var key in $this[eventArr]){
            if(key == type) isHas = true;
        }
        if(!isHas) $this[eventArr][type] = [];
        $this[eventArr][type].push(callback);
    }
    //手动触发绑定到播放器实例上的事件-公有方法
    trigger(type, e, data){
        var $this = this;
        if(!!$this[eventArr][type] && $this[eventArr][type].length > 0){
            $.each($this[eventArr][type], function(i, callback){
                callback(e, data);
            });
        }
    }
    //事件，对外绑定
    [events]() {
        var $this = this;
        
        var events = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'ended', 'error', 'loadeddata', 
            'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'readystatechange', 
            'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting'];
        
        $.each(events, function(i, eventName) {
            $this.$audio.off(eventName + ".events").on(eventName + ".events", function(e) {
                if($this[options].debug){
                    console.log(e.type);
                    $("#test").val(e.type);
                }
                $this.trigger(e.type, e, $this);//触发绑定到播放器实例上的Media事件（媒介触发的事件）
            });
        });
    }
 }

 export default AudioPlayer;